package com.api.rc.controller;

import com.api.core.annotation.PowerEnable;
import com.api.core.config.AuthUser;
import com.api.core.controller.Ctrl;
import com.api.core.response.Result;
import com.api.core.response.ResultEnum;
import com.api.core.response.ResultGenerator;
import com.api.rc.enums.PlayerGameStatus;
import com.api.rc.enums.RoomFee;
import com.api.rc.enums.RoomStatus;
import com.api.rc.form.CreateRoomForm;
import com.api.rc.form.GameResultForm;
import com.api.rc.service.RapidChallengeService;
import com.api.rc.vo.PlayerVo;
import com.api.rc.vo.RcOverviewVo;
import com.api.rc.vo.RoomVo;
import com.api.user.exception.CoinChangedException;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.validator.constraints.Range;
import org.springframework.security.core.Authentication;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author RenQiang
 * @date 2021/7/12
 */
@Slf4j
@RestController
@RequestMapping(value = "/rapid-challenge")
@PowerEnable(name = "快速挑战", url = "/rapid-challenge")
@Api(value = "快速挑战", tags = {RapidChallengeController.API_TAG})
@Validated
public class RapidChallengeController extends Ctrl {
    public static final String API_TAG = "快速挑战";

    private final RapidChallengeService rapidChallengeService;

    public RapidChallengeController(RapidChallengeService rapidChallengeService) {
        this.rapidChallengeService = rapidChallengeService;
    }

    @PostMapping("/create-room")
    @ApiOperation(value = "创建房间", tags = {API_TAG}, notes = "创建房间")
    public Result createRoom(Authentication authentication,
                             @Valid @RequestBody CreateRoomForm createRoomForm) {
        AuthUser authUser = getAuthUser(authentication);
        try {
            rapidChallengeService.createRoom(authUser.getId(), createRoomForm);
        } catch (IllegalArgumentException e) {
            log.error("创建房间失败", e);
            return ResultGenerator.genFailResult(ResultEnum.FAIL.getCode(), e.getMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    @PostMapping("/start-game")
    @ApiOperation(value = "开始游戏", tags = {API_TAG}, notes = "开始游戏")
    public Result createRoom(@ApiParam(value = "房间ID") @RequestParam Long roomId) throws CoinChangedException {
        try {
            try {
                rapidChallengeService.startGame(roomId);
            } catch (CoinChangedException ignore) {
                rapidChallengeService.startGame(roomId);
            }
        } catch (IllegalArgumentException e) {
            log.error("创建房间失败", e);
            return ResultGenerator.genFailResult(ResultEnum.FAIL.getCode(), e.getMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/get-all-room-fees")
    @ApiOperation(value = "获取所有房费列表", tags = {API_TAG}, notes = "获取所有房费列表")
    public Result getAllRoomFees() {
        List<Map<String, Object>> mapList = Arrays.stream(RoomFee.values())
                .map(f -> ImmutableMap.<String, Object>of("key", f.name(), "fee", f.getFee()))
                .collect(Collectors.toList());
        return ResultGenerator.genSuccessResult(mapList);
    }

    @GetMapping("/list-room-by-page")
    @ApiOperation(value = "分页查询房间", tags = {API_TAG}, notes = "分页查询房间")
    public Result listRoomByPage(@ApiParam(value = "游戏ID") @RequestParam(required = false) Long gameId,
                                 @ApiParam(value = "房间类型") @RequestParam(required = false) Boolean isPublic,
                                 @ApiParam(value = "房间费用") @RequestParam(required = false) RoomFee roomFee,
                                 @ApiParam(value = "页号") @RequestParam(defaultValue = "1") Integer page,
                                 @ApiParam(value = "分页大小") @RequestParam(defaultValue = "10") Integer size) {
        Map<String, Object> queryParams = new HashMap<>(8);
        if (gameId != null) {
            queryParams.put("gameId", gameId);
        }
        if (isPublic != null) {
            queryParams.put("isPublic", isPublic);
        }
        if (roomFee != null) {
            queryParams.put("roomFee", roomFee);
        }
        queryParams.put("roomStatus", RoomStatus.WaitingToStart);
        PageInfo<RoomVo> pageInfo = rapidChallengeService.listByPage(queryParams, page, size);
        pageInfo.getList()
                .forEach(roomVo -> {
                    roomVo.setPlatformRewardCoins(null);
                    roomVo.setHostEarnCoins(null);
                });
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @GetMapping("/list-game-by-page")
    @ApiOperation(value = "分页查询参与过的比赛", tags = {API_TAG}, notes = "分页查询参与过的比赛")
    public Result listGameByPage(Authentication authentication,
                                 @ApiParam(value = "房间类型") @RequestParam(required = false) Boolean isPublic,
                                 @ApiParam(value = "游戏状态") @RequestParam(required = false) PlayerGameStatus gameStatus,
                                 @ApiParam(value = "页号") @RequestParam(defaultValue = "1") Integer page,
                                 @ApiParam(value = "分页大小") @RequestParam(defaultValue = "10") Integer size) {
        AuthUser authUser = getAuthUser(authentication);
        Map<String, Object> queryParams = new HashMap<>(8);
        if (isPublic != null) {
            queryParams.put("isPublic", isPublic);
        }
        if (gameStatus != null) {
            queryParams.put("gameStatus", gameStatus);
        }
        queryParams.put("playerId", authUser.getId());
        PageInfo<RoomVo> pageInfo = rapidChallengeService.listByPage(queryParams, page, size);
        pageInfo.getList()
                .forEach(roomVo -> {
                    roomVo.setPlatformRewardCoins(null);
                    roomVo.setHostEarnCoins(null);
                });
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @PostMapping("/complete-game")
    @ApiOperation(value = "结束游戏并上传成绩", tags = {API_TAG}, notes = "结束游戏并上传成绩")
    public Result completeGame(@Valid @RequestBody GameResultForm gameResultForm) throws CoinChangedException {
        try {
            try {
                rapidChallengeService.completeGame(gameResultForm);
            } catch (CoinChangedException ignore) {
                rapidChallengeService.completeGame(gameResultForm);
            }
        } catch (IllegalArgumentException e) {
            log.error("保存游戏结果失败", e);
            return ResultGenerator.genFailResult(ResultEnum.FAIL.getCode(), e.getMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/get-game-result")
    @ApiOperation(value = "获取比赛结果", tags = {API_TAG}, notes = "获取比赛结果")
    public Result getGameResult(@ApiParam(value = "房间ID") @RequestParam Long roomId) {
        GameResultForm gameResult = rapidChallengeService.getGameResult(roomId);
        return ResultGenerator.genSuccessResult(gameResult);
    }

    @PostMapping("/confirm-game-result")
    @ApiOperation(value = "确认比赛结果并给主持人打分", tags = {API_TAG}, notes = "确认比赛结果并给主持人打分")
    public Result confirmGameResult(Authentication authentication,
                                    @ApiParam(value = "房间ID") @RequestParam Long roomId,
                                    @ApiParam(value = "给主持人的评分") @RequestParam(required = false, defaultValue = "5") @Range(min = 0, max = 5) Integer starToHost) throws CoinChangedException {
        AuthUser authUser = getAuthUser(authentication);
        try {
            rapidChallengeService.confirmGameResult(authUser.getId(), roomId, starToHost);
        } catch (IllegalArgumentException e) {
            log.error("确认比赛结果并给主持人打分失败", e);
            return ResultGenerator.genFailResult(ResultEnum.FAIL.getCode(), e.getMessage());
        }
        return ResultGenerator.genSuccessResult();
    }

    @GetMapping("/get-overview")
    @ApiOperation(value = "获取快速挑战总览", tags = {API_TAG}, notes = "获取快速挑战总览")
    public Result getOverview() {
        RcOverviewVo rcOverviewVo = rapidChallengeService.getOverview();
        return ResultGenerator.genSuccessResult(rcOverviewVo);
    }

    @GetMapping("/list-by-page")
    @ApiOperation(value = "分页查询快速挑战订单", tags = {API_TAG}, notes = "分页查询快速挑战订单")
    public Result listByPage(@ApiParam(value = "房间类型") @RequestParam(required = false) Boolean isPublic,
                             @ApiParam(value = "房间状态") @RequestParam(required = false) RoomStatus roomStatus,
                             @ApiParam(value = "开始时间") @RequestParam(required = false) Date minDate,
                             @ApiParam(value = "结束时间") @RequestParam(required = false) Date maxDate,
                             @ApiParam(value = "页号") @RequestParam(defaultValue = "1") Integer page,
                             @ApiParam(value = "分页大小") @RequestParam(defaultValue = "10") Integer size) {
        Map<String, Object> queryParams = new HashMap<>(8);
        if (isPublic != null) {
            queryParams.put("isPublic", isPublic);
        }
        if (roomStatus != null) {
            queryParams.put("roomStatus", roomStatus);
        }
        if (minDate != null) {
            queryParams.put("minDate", minDate);
        }
        if (maxDate != null) {
            queryParams.put("maxDate", maxDate);
        }
        PageInfo<RoomVo> pageInfo = rapidChallengeService.listByPage(queryParams, page, size);
        return ResultGenerator.genSuccessResult(pageInfo);
    }

    @GetMapping("/get-player-detail")
    @ApiOperation(value = "获取玩家详情", tags = {API_TAG}, notes = "获取玩家详情")
    public Result getPlayerDetail(@ApiParam(value = "房间ID") @RequestParam Long roomId) {
        List<PlayerVo> playerVos = rapidChallengeService.getPlayerDetail(roomId);
        return ResultGenerator.genSuccessResult(playerVos);
    }
}
